<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>双人对战五子棋</title>
		<style>
			*{
				margin:0px;
				padding:0px;
			}
			#mycanvas{
				background-color: darkgray;
				display:block;
				margin-left:300px;
				margin-top:50px;
				box-shadow: -5px -5px 15px darkgray,5px 5px 15px darkgray;
				cursor: pointer;
				display:none;
			}
			#text{
				margin:0 auto;
				width:290px;
				height: 20px;
				border:none;
				margin-top:50px;
				margin-bottom:60px;
				border:5px solid blue;
			}
			#show{
				margin-left:60px;
				height: 50px;
				font-size:16px;
				font-weight:bold;
				background-color: aquamarine;
			}
			#box{
				width: 300px;
				height: 300px;
				background-color: darkgray;
				margin:0 auto;
			}
			#restart{
				margin:0 auto;
				display:block;
				margin-bottom:50px;
			}
			#h1{
				color:pink;
				animation:1s myh1 linear infinite; 
			}
			@keyframes myh1{
				0%{
					opacity:1;
				}
				50%{
					opacity:0.3;
				}
				100%{
					opacity:1;
				}
			}
		</style>
	</head>
	<body>
		<button id="restart">重新开始</button>
		<div id="box">
			<h1 id="h1">欢迎来到五子棋世界</h1>
			<input type="text" id="text" placeholder="请输入你要选择的棋盘宽高">
			<button id="show">点击显示棋盘开始游戏</button>
		</div>
		<canvas id="mycanvas" width="480" height="480"></canvas>
	</body>
	<script src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
	<script>
		document.getElementById("restart").onclick = function() {
			window.location.reload();
		}
		//自定义棋盘大小
		$('#show').click(function() {
			$('#mycanvas').show(); //隐藏div
			$('#box').hide(); //显示画布
			var a = $('#text').val(); //获取用户填写的高度
			// var b = $('#text1').val();
			var mycanvas = document.getElementById("mycanvas");
			mycanvas.width = a; //这里是用户填写的宽度注意这里必须使用原生js的方法
			mycanvas.height = a; //这里是用户填写的高度getContext是DOM对象的方法，也就是原生js方法
			//，不能用jQuery对象直接获取。
			var context = mycanvas.getContext("2d");
			var mycanvasW = a; //画布的宽度由用户定义
			//console.log(mycanvasvasW)
			// var mycanvasvasH=b;
			var rows = 15; //棋盘的行列数，棋盘大小默认值为15*15
			//计算棋盘的网格大小
			var chessesW = mycanvasW / (rows + 1);
			//var chessesH=parseInt(mycanvasvasH/(rows+1));
			//console.log(mycanvasvasW)
			//console.log(chessesW)
			for (var i = 0; i < 15; i++) {
				var x1 = chessesW;
				var y1 = chessesW * (i + 1);
				var x2 = mycanvasW - chessesW;
				var y2 = chessesW * (i + 1);
				context.moveTo(x1, y1);//这里绘制的是横线开始位置
				context.lineTo(x2, y2);//这里是绘制横线的结束位置
				context.moveTo(y1, x1);//这里是竖线的开始位置
				context.lineTo(y2, x2);//这里是竖线的结束位置
				context.stroke();//绘制图线
			}
			//二、点击棋盘，绘制棋子
			//三、区分玩家，绘制黑子和白子
			var isBlack = true;
			mycanvas.onclick = function(ev) {
				//获取鼠标点击位置坐标x，y
				var x = ev.offsetX;
				var y = ev.offsetY;
				//计算棋子的中心点坐标x0,y0
				var x0 = Math.round(x / chessesW) * chessesW; //这里使用的是四舍五入的方法
				var y0 = Math.round(y / chessesW) * chessesW; //这里使用的是四舍五入的方法
				//console.log(x0, y0)
				//五、计算落子位置与数组元素对应下标
				var i, k;
				i = y0 / chessesW - 1; //这是相当于行坐标
				k = x0 / chessesW - 1; //这里相当于列坐标
				//console.log(i, k)
				//六、判断此处是否已经有棋子
				if (chessesArr[i][k] != 0) {
					alert("此处已经有棋子，不能重复落子！");
					return;
				}
				//三、区分玩家，黑子和白子
				if (isBlack) {
					context.fillStyle = "black";
					chessesArr[i][k] = 2 // 1 黑子2，白子1
				} else {
					context.fillStyle = "white";
					chessesArr[i][k] = 1 // 1 黑子2，白子1
				}

				context.beginPath();
				context.arc(x0, y0, chessesW * 0.4, 0, Math.PI * 2);
				context.fill();
				//七、棋子绘制完成，判断当前玩家是否五子相连
				var isWinner = winner(i, k);
				if (isWinner) {
					setTimeout(function() {
						alert(isBlack ? "黑方胜!!" : "白方胜");
						mycanvas.onclick = null;
					}, 20)
				}
				setTimeout(function() {
					isBlack = !isBlack;
				}, 40)
			}
			//四、创建数组--与棋盘上所有棋子对应的数组
			var chessesArr = new Array(rows); //输入一个数字就是数组的数量为15
			for (var i = 0; i < chessesArr.length; i++) {
				// chessesArr[i] = 数组
				var tempArr = new Array(rows); //声明一个临时数组
				tempArr.fill(0); //在里面放置内容为0
				chessesArr[i] = tempArr //在将其赋给一维数组中的每个值变成二维数组
			}
			//七、判断胜负
			function winner(i, k) {//声明一个函数，两个变量。
				//在四个方向上有一个方向上五子相连，则本方胜
				if (winerRow(i, k) || winerCol(i, k) || winerXY(i, k) || winerYX(i, k)) {//判断如果上面4中条					都满足。
					return true;//返回值为true
				}
				return false;//否则就返回false
			}
			//7.1在行上如果有五子相连，则返回true
			function winerRow(i, k) {
				//从[i][k]向左统计连续相同棋子个数
				var count = 1;
				for (var t = k - 1; t >= 0; t--) {
					if (chessesArr[i][t] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				//从[i][k]向右统计连续相同棋子个数
				for (var t = k + 1; t < rows; t++) {
					if (chessesArr[i][t] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				if (count >= 5) {
					return true;
				}
				return false;
			}
			//7.2在列上五子相连
			function winerCol(i, k) {
				//从[i][k]向下统计连续相同棋子个数
				var count = 1;
				for (var t = i + 1; t < rows; t++) {
					if (chessesArr[t][k] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				//从[i][k]向上统计连续相同棋子个数
				for (var t = i - 1; t >= 0; t--) {
					if (chessesArr[t][k] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				if (count >= 5) {
					return true;
				}
				return false;
			}
			//7.3在正斜方向（/）上五子相连
			function winerXY(i, k) {
				var count = 1;//定义一个变量用来保存棋子的数量
				//统计[i][k]位置左下方向上连续相同的棋子个数
				for (var m = i + 1, n = k - 1; m < rows && n >= 0; m++, n--) {
					if (chessesArr[m][n] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				//统计[i][k]位置右上方向连续相同的棋子个数
				for (var m = i - 1, n = k + 1; m >= 0 && n < rows; m--, n++) {
					if (chessesArr[m][n] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				if (count >= 5) {
					return true;
				}
				return false;
			}
			//7.2在反斜方向(\)上五子相连
			function winerYX(i, k) {
				var count = 1;
				//统计[i][k]位置右下方向上连续相同的棋子个数
				for (var m = i + 1, n = k + 1; m < rows && n < rows; m++, n++) {
					if (chessesArr[m][n] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				//统计[i][k]位置左上方向连续相同的棋子个数
				for (var m = i - 1, n = k - 1; m >= 0 && n >= 0; m--, n--) {
					if (chessesArr[m][n] == chessesArr[i][k]) {
						count++;
					} else {
						break;
					}
				}
				console.log(count);
				if (count >= 5) {
					return true;
				}
				return false;
			}

		});
	</script>

</html>
